#include "encdec.h"
#include <stdio.h>
#include <stdlib.h>

void aes_decrypt(const char * key, const unsigned char * srcdata,size_t src_len, unsigned char * result){
   unsigned char ivec[AES_BLOCK_SIZE]={0};

AES_KEY aeskey;
int a=AES_set_decrypt_key((const unsigned char *)key, 128, &aeskey);
AES_cbc_encrypt(srcdata, result, src_len,&aeskey, ivec, AES_DECRYPT);

}

size_t getAES_enc_result_len(size_t src_len){

size_t len=src_len;
   if(len%AES_BLOCK_SIZE!=0){
    len=len+AES_BLOCK_SIZE-len%AES_BLOCK_SIZE;
   }

return len;
}

void aes_encrypt(const char * key, const unsigned char * srcdata,unsigned int src_len, unsigned char * result){

unsigned char ivec[AES_BLOCK_SIZE]={0};

AES_KEY aeskey;
int a=AES_set_encrypt_key((const unsigned char *)key, 128, &aeskey);



AES_cbc_encrypt(srcdata, result, src_len,&aeskey, ivec, AES_ENCRYPT);

}


int   rsa_sha256_sign(const unsigned char * srcdata, size_t src_len, unsigned char ** result){

unsigned char  hash[SHA256_DIGEST_LENGTH];

SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, srcdata, src_len);
SHA256_Final(hash, &ctx);


RSA * rsa= loadPriveteKey("private.pem",nullptr);

printf("signature buf len  :%d\n",RSA_size(rsa));

*result=new unsigned char[RSA_size(rsa)];


int siglen;
int ret = RSA_sign(NID_sha256,hash,SHA256_DIGEST_LENGTH,*result,(unsigned int *)&siglen,rsa);
if(rsa!=nullptr){
   RSA_free(rsa);
}
if(ret==1){
   printf("RSA_sign success\n");

}else{

   printf("RSA_sign failed\n");
}

return siglen;
}

int   rsa_sha256_verify(const unsigned char * srcdata, size_t src_len, unsigned char * sigbuf,int siglen){
  RSA * rsa= loadPublickey();

unsigned char  hash[SHA256_DIGEST_LENGTH];
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, srcdata, src_len);
SHA256_Final(hash, &ctx);

     
int  ret=  RSA_verify(NID_sha256,hash,SHA256_DIGEST_LENGTH,sigbuf,siglen,rsa);
if(rsa!=nullptr){
   RSA_free(rsa);
}
if(ret==1){
   printf("RSA_verify success\n");
   return 1;

}else if(ret==0){
   printf("RSA_verify failed\n");
   return 0;
}else{
   ERR_print_errors_fp(stderr);
   return 0;
}

}


RSA * loadPriveteKey(const char * private_key_path,const char * password){
FILE * fp=fopen(private_key_path,"r");
if (fp==nullptr)
{
   printf("open file failed %s\n",private_key_path);
   return nullptr;
}

RSA   * rsa= nullptr;

EVP_PKEY * pkey= PEM_read_PrivateKey(fp,NULL,NULL,(void *)password);

fclose(fp);

if(pkey!=nullptr){
 rsa=  EVP_PKEY_get1_RSA(pkey);
}

if(rsa==nullptr){
   ERR_print_errors_fp(stderr);
}

EVP_PKEY_free(pkey);
return rsa;
}

RSA * loadPublickey(){

 const char * public_key=R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35K9XfAWU0o7qpNZ6oV
pW7Zk9/YU/+C7wzDxU0+VF/1ZG2mnKgerR+sGwpwcPZ5basPfszSJXaZSpAk39gk
stZWpXhcAaJylGqINOqgI++mL2TwSsNCbA7W/L2JqwqkrRHY50IgCwl8eYe1+3ue
0LZPeLRYOYIXNEv4dgxkVBhFTQwBWsLaNECz8lwuFgQ5TljL031NnDifm+s4bDyN
t0oXcjGOSmRs1SyE2sRLe6o6ZZ6wZNyb7SEvEIamjHrsuJSxTN9LJk8Fnqzpnl+5
LTZ1YcAMw9goYDrpgfAr8OLxAkILdmJfY3qLafLGIyDslMpSeQqzJAGTcA2ei3fO
uwIDAQAB
-----END PUBLIC KEY-----)";


   BIO * bio= BIO_new_mem_buf(public_key, -1);

   RSA * rsa= PEM_read_bio_RSA_PUBKEY(bio,NULL,NULL,NULL);

   BIO_free_all(bio);

if(rsa==nullptr){
   ERR_print_errors_fp(stderr);
}

return rsa;
}